// 练习函数指针
/* 
  函数指针的定义: 返回值 (*fp)(参数列表) = &func;
  关于类型的转换可以参考：https://zhuanlan.zhihu.com/p/152247037
*/
#include <iostream>

const double * f1(const double arr[], int n);
const double * f2(const double *a1, int n);
const double * f3(const double *a1, int n);
typedef const double * (*FUNP) (const double *, int);

using namespace std;
int main()
{
    //1. 使用指针调用f1，同时打印出函数指针和调用的结果
    const double arguments[3] = {1112.3, 1542.6, 2227.9}; 
    //创建函数指针
    const double * (*p1) (const double *, int) = f1;
    cout << "Function Address and value:\n";
    cout << (*p1)(arguments, 3) << " : "<< *(*p1)(arguments, 3) << "\n";
    // 使用typedef形式声明
    FUNP funp = f1;
    cout << "Use typdedef: " << funp(arguments,3) << endl;

    //2.使用auto测试f2
    auto p2 = f2;
    cout << (*p2)(arguments, 3) << " : " << *(*p2)(arguments, 3) << "\n";

     //3. 使用函数指针数组批量调用函数
    cout << "Using funtion pointer array typedef" << endl;
    const double *(* p_func_array[3]) (const double *, int) = {f1, f2, f3};
    FUNP p_func_array_new[3] = {f1, f2, f3};
        for (size_t i = 0; i < 3; i++)
    {   
        FUNP p = p_func_array[i];
        cout << p(arguments, 3) << " : " << *(p(arguments, 3)) << "\n";
    }
    
    cout << "Using funtion pointer array" << endl;
    for (size_t i = 0; i < 3; i++)
    {   
        const double *(*a_func_p)(const double *, int) = p_func_array[i];
        cout << (*a_func_p)(arguments, 3) << " : " << *(*a_func_p)(arguments, 3) << "\n";
    }
    
    //4.定义一个指向p_func_array指针的指针
    FUNP *p_func_array_new_p = &p_func_array_new[0];

    cout << "Using function pointer array pointer" << endl;
    //const double *(*(*pd)[3])(const double *, int) = &pa;
    const double *(*(* p_func_array_p)[3])(const double *, int) = &p_func_array;
    cout <<  (*p_func_array_p)[0](arguments, 3) << " : " << *((*p_func_array_p)[0](arguments, 3)) << endl;
    return 0; 
}

const double * f1(const double *arr, int n) {
    return arr;
}

const double * f2(const double arr[], int n) {
    return arr + 1;
}

const double * f3(const double array[], int n) {
    return array + 2;
}
